package com.qf.business.user.core.controller;

import com.qf.business.user.core.service.SysPowerService;
import com.qf.commons.core.utils.QfBeanUtils;
import com.qf.commons.data.result.R;
import com.qf.data.user.dto.SysPowerCheckDto;
import com.qf.data.user.dto.SysPowerPnameDto;
import com.qf.data.user.entity.SysPower;
import com.qf.data.user.vo.input.SysPowerInput;
import com.qf.data.user.vo.output.SysPowerTreeOutput;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * author Ken
 * create_time 2022/8/30
 */
@RestController
@RequestMapping("/sys/power")
@Slf4j
public class PowerController {

    @Autowired
    private SysPowerService powerService;

    /**
     * 查询所有权限的列表
     * @return
     */
    @RequestMapping("/list")
    public R list(){
        List<SysPowerPnameDto> result = powerService.queryPnameList();
        return R.create(result);
    }

    /**
     * 新增权限
     * @return
     */
    @RequestMapping("/insert")
    public R insert(@Valid SysPowerInput sysPowerInput){
        log.debug("[power insert] 新增权限 - {}", sysPowerInput);
        //转换
        SysPower sysPower = QfBeanUtils.copyBean(sysPowerInput, SysPower.class);
        //保存
        powerService.save(sysPower);
        return R.create("succ");
    }

    /**
     * 根据角色id 查询 权限树，以及当前角色拥有哪些权限
     *
     *
     * //查询出来的结果：
     * List<SysPowerCheckDto> sysPowerCheckDtos;
     * List - [
     *    SysPowerCheckDto(id:1, pid:null, powerName:"行政管理",...,checked:true),
     *    SysPowerCheckDto(id:2, pid:1, powerName:部门管理,...,checked:true),
     *    SysPowerCheckDto(id:3, pid:2, powerName:添加部门,...,checked:true),
     *    SysPowerCheckDto(id:8, pid:null, powerName:员工管理,...,checked:true)
     * ]
     *
     * //转换的过程 ->
     * Map<Integer, SysPowerTreeOutput>
     *
     * 循环 -> List
     *   {
     *       //判断 pid 是不是 null
     *       -------
     *       //如果 pid 是 null，则直接将当前对象SysPowerCheckDto  转换成  SysPowerTreeOutput
     *       //放入Map集合中 - key:权限id, value:SysPowerTreeOutput
     *       -------
     *       //如果pid不是null，说明有一个父权限，该如何找到这个父权限（将当前权限作为子权限 放进去）？
     *       //通过pid 去 map中查询到父权限树的节点对象SysPowerTreeOutput，将当前权限对象 转换成 SysPowerTreeOutput，放入父权限对象的children中
     *   }
     *
     *
     * //需要输出的结果：
     * [
     *   {id:1, label:行政管理, checked:true, children: [{
     *       id:2, label:部门管理, children: [{
     *           id:3, label:添加部门, checked:false, children: null
     *       }]
     *   },{}]},
     *   {id:8, label:员工管理, children: []}
     * ]
     *
     * @return
     */
    @RequestMapping("/queryPowerTreeByRid")
    public R<List<SysPowerTreeOutput>> queryPowerTreeByRid(Integer rid){
        //根据角色 查询 所有权限以及每条权限的选中情况
        List<SysPowerCheckDto> sysPowerCheckDtos = powerService.queryPowersCheckByRid(rid);

        //输出的结果
        List<SysPowerTreeOutput> powerTrees = new ArrayList<>();

        //准备一个Map
        //key - 表示权限id ， value - 表示权限对应的SysPowerTreeOutput
        Map<Integer, SysPowerTreeOutput> powerMap = new HashMap<>();
        
        //循环遍历查询的权限列表
        for (SysPowerCheckDto sysPowerCheckDto : sysPowerCheckDtos) {
            //转换SysPowerTreeOutput对象
            SysPowerTreeOutput sysPowerTreeOutput = new SysPowerTreeOutput()
                    .setId(sysPowerCheckDto.getId())
                    .setLabel(sysPowerCheckDto.getPowerName())
                    .setChecked(sysPowerCheckDto.isChecked());

            //判断是否有父节点
            if(sysPowerCheckDto.getPid() == null) {
                //说明当前节点是顶级节点
                powerTrees.add(sysPowerTreeOutput);
            } else {
                //说明当前节点有父节点
                //找到父节点（父权限）
                SysPowerTreeOutput parentPowerTreeOutput = powerMap.get(sysPowerCheckDto.getPid());
                parentPowerTreeOutput.addChildren(sysPowerTreeOutput);
            }

            //将当前节点放入Map集合
            powerMap.put(sysPowerTreeOutput.getId(), sysPowerTreeOutput);
        }
        
        return R.create(powerTrees);
    }
}
